package com.geek.rest;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.lang.annotation.Annotation;
import java.util.*;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;


public class RequestTemplate {

    public static Set<Class<? extends Annotation>> SUPPORT_ANNOTATION_TYPES = Collections.unmodifiableSet(
            new LinkedHashSet<>(Arrays.asList(
                    PathParam.class, QueryParam.class,
                    MatrixParam.class, FormParam.class,
                    CookieParam.class, HeaderParam.class
            ))
    );

    private String method;

    public String getMethod() {
        return method;
    }

    public String getUriTemplate() {
        return uriTemplate;
    }

    private String uriTemplate;

    private Set<String> consumers = new LinkedHashSet<>();

    private Set<String> produces = new LinkedHashSet<>();

    /**
     * 方法请求的注解 对应的 注解元信息
     */
    private Map<Class<? extends Annotation>, List<AnnotatedParamMetadata>> annotatedParamMetadataMap = new HashMap<>();


    public RequestTemplate method(String method) {
        this.method = method;
        return this;
    }

    public RequestTemplate urlTemplate(String uriTemplate) {
        this.uriTemplate = uriTemplate;
        return this;
    }

    public RequestTemplate annotatedParamMetadata(List<AnnotatedParamMetadata> annotatedParamMetadata) {
        annotatedParamMetadata.forEach(this::annotatedParamMetadata);
        return this;
    }

    public RequestTemplate annotatedParamMetadata(AnnotatedParamMetadata annotatedParamMetadata) {
        Class<? extends Annotation> annotationType = annotatedParamMetadata.getAnnotationType();
        annotatedParamMetadataMap.computeIfAbsent(annotationType, type -> new LinkedList<>()).add(annotatedParamMetadata);
        return this;
    }


    public RequestTemplate consumers(String... consumers) {
        if (consumers != null) {
            this.consumers.addAll(Arrays.asList(consumers));
        }
        return this;
    }

    public RequestTemplate produces(String... produces) {
        if (produces != null) {
            this.produces.addAll(asList(produces));
        }
        return this;
    }

    public List<AnnotatedParamMetadata> getAnnotatedParamMetadata(Class<? extends Annotation> annotationType) {
        return annotatedParamMetadataMap.getOrDefault(annotationType, emptyList());
    }


    public Set<String> getConsumers() {
        return consumers;
    }

    public MediaType getMediaType() {
        return consumers.isEmpty() ? MediaType.APPLICATION_JSON_TYPE : MediaType.valueOf(consumers.iterator().next());
    }

    public Set<String> getProduces() {
        return produces;
    }
}
